/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.deployment.daogenerico;

import br.com.deployment.entidade.empresa.Cartorio;
import br.com.deployment.servico.CartorioServico;
import br.com.deployment.utilitario.Msg;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author elyjr
 */
public abstract class DaoGenerico<T> {

    @PersistenceContext
    private EntityManager em;
    private String CARTORIO = "cartorio";
    private String SETCARTORIO = "setCartorio";
    @EJB
    private CartorioServico cartorioServico;
    private Class<T> entity;

    public DaoGenerico(Class<T> entity) {
        this.entity = entity;
    }

    private T reflections(T entityRf) {
        try {
            Field fieldR = null;

            Class cls = Class.forName(entityRf.getClass().getName());

            for (Field field : cls.getDeclaredFields()) {
                if (field.getName().equalsIgnoreCase(CARTORIO)) {
                    Method mth = cls.getMethod(SETCARTORIO, Cartorio.class);
                    mth.invoke(entityRf, cartorioServico.getCartorioContext());
                    return entityRf;
                }
            }
        } catch (InvocationTargetException ex) {
            Logger.getLogger(DaoGenerico.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(DaoGenerico.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(DaoGenerico.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(DaoGenerico.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(DaoGenerico.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(DaoGenerico.class.getName()).log(Level.SEVERE, null, ex);
        }
        return entityRf;

    }

    public void save(T entity) {
        try {
            entity = reflections(entity);
            em.persist(entity);
        } catch (Exception e) {
            Msg.messagemError("Erro ao Salvar");
            throw new IllegalArgumentException("Erro ao Salvar !");
        }
    }

    public void delete(T entity) {
        T entityToBeRemoved = em.merge(entity);
        em.remove(entityToBeRemoved);
    }

    public T update(T entity) {
        T edited = null;
        try {
            edited = em.merge(entity);
        } catch (Exception e) {
            Msg.messagemError("Erro ao Atualizar");
            throw new IllegalArgumentException("Erro ao Atualizar !");
        }
        return edited;
    }

    public T find(int entityID) {
        try{
            return em.find(entity, entityID);
        } catch (Exception e) {
            Msg.messagemError("Erro ao Buscar");
            throw new IllegalArgumentException("Erro ao Buscar (find(Id)) !");
        }
    }

    public T find(Long entityID) {
        return em.find(entity, entityID);
    }

    public List<T> findAll() {
        return em.createQuery("select e from " + entity.getSimpleName() + " e").getResultList();
    }

    public EntityManager getEm() {
        return em;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }
}
